import numpy as np

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]

n_epochs = 10000
m = 100
learning_rate = 0.001

theta = np.random.randn(2, 1)
for _ in range(n_epochs):
    #
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    for i in range(m):
        xi = X_b[i:i + 1]
        yi = y[i:i + 1]
        gradients = xi.T.dot(xi.dot(theta) - yi)
        theta -= learning_rate * gradients

print(theta)
